/*
# Vulnerability.cpp
#
# Copyright (c) 2012 Attique Dawood, Awais Aslam
#
# This file is part of Vulnerability program provided with Automated Worm Fingerprinting.
#
# This software is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this software.  If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################
Getting Hostname: http://guy-lecky-thompson.suite101.com/socket-programming-gethostbyname-a19557
*/

#include <Vulnerability.h>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <openssl/rc4.h>
#include <iostream>
#include <string>
#include <bitset>
#include <vector>
#include <sstream>
#include <fstream>

#ifdef WIN32
#include <WinSock2.h>
#include <process.h>
#include <Windows.h>
#else
#include <arpa/inet.h>		// inet_ntoa()
#include <netdb.h>			// gethostbyname(), connect(), send(), recv()
#include <pthread.h>
#endif

using std::cerr;
using std::cout;
using std::endl;
using std::fill;
using std::string;
using std::bitset;
using std::vector;
using std::stringstream;
using std::fstream;

// Platform specific #defines
#ifdef WIN32
#define THREAD_RETURN_TYPE void
#define CLOSE closesocket

#else
#define THREAD_RETURN_TYPE void*
#define CLOSE close
#endif

// Threads.
THREAD_RETURN_TYPE Vulnerability (void *);
THREAD_RETURN_TYPE Worm_V01 (void *);
THREAD_RETURN_TYPE Worm_V02 (void *);
THREAD_RETURN_TYPE Worm_V02_Receiver (void *);

#ifdef WIN32
HANDLE tVulnerability;
HANDLE tWorm_V01;
HANDLE tWorm_V02;
HANDLE tWorm_V02_Receiver;
HANDLE MutexLock = CreateMutex (NULL, FALSE, NULL);
#else
pthread_t tVulnerability;
pthread_t tWorm_V01;
pthread_t tWorm_V02;
pthread_t tWorm_V02_Receiver;
pthread_mutex_t MutexLock = PTHREAD_MUTEX_INITIALIZER;
#endif

// Network related.
// ****************************************** #Defintions ***********************************************
#define  MAXBUFFERSIZE	512		// Maximum default buffersize.
#define  SERVERPORT		7010	// Vulnerability Server thread will be listening on this port by default.
// ******************************************************************************************************

// *********************************************** Globals ************************************************
int SocketFD;

//struct hostent *he;
struct sockaddr_in ServerAddress;
struct sockaddr_in ClientAddress;

// Buffer.
char Buffer[MAXBUFFERSIZE];
int NumOfBytesSent;
int NumOfBytesReceived;

// Miscellaneous Variables.
int Yes = 1;
int AddressLength;
int errorcheck;
#ifdef WIN32
int sin_size;
#else
socklen_t sin_size;
#endif

vector<string> PeerIPList;	// Used by Worm_V02.

// Global Vulnerability object.
CVulnerability VulnerabilityInstance;

CVulnerability::CVulnerability(): Mode(MODE_NORMAL)
{
}

void CVulnerability::Initialize(MODE_OF_OPERATION pMode)
{
	Mode = pMode;
	switch(Mode)
	{
		case MODE_NORMAL: default:
		{
			InfectionFlags |= MODE_INFECTED_NONE_FLAG;
			break;
		}
		case MODE_INFECTED_V01:
		{
			InfectionFlags |= MODE_INFECTED_V01_FLAG;
			break;
		}
		case MODE_INFECTED_V02:
		{
			InfectionFlags |= MODE_INFECTED_V02_FLAG;
			break;
		}
		case MODE_INFECTED_ALL:
		{
			InfectionFlags |= MODE_INFECTED_ALL_FLAG;
			break;
		}
	}

	#ifdef WIN32
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
	{
		cerr << "WSAStartup failed." << endl;
		exit(1);
	}
	#endif

	// Server socket.
	SafeCall (SocketFD = socket (AF_INET, SOCK_DGRAM, 0), "socket()");
	// Server address initialization for binding.
	ServerAddress.sin_family = AF_INET;				// Socekt family.
	ServerAddress.sin_addr.s_addr = INADDR_ANY;		// Setting server IP. INADDR_ANY is the localhost IP.
	ServerAddress.sin_port = htons (SERVERPORT);	// Setting server port.
	fill ((char*)&(ServerAddress.sin_zero), (char*)&(ServerAddress.sin_zero)+8, '\0');

	// bind()
	SafeCall (bind (SocketFD, (sockaddr *)&ServerAddress, sizeof (ServerAddress)), "bind()");

}

void CVulnerability::Run()
{
	cout << "=======================================================" << endl;
	// Infected Threads.
	// Check for Worm_V01 infection:
	if (InfectionFlags[0] == 1)
	{
		cout << "Starting infection thread Worm_V01..." << endl;
		#ifdef WIN32
		tWorm_V01 = (HANDLE)_beginthread (Worm_V01, 0, NULL);
		#else
		pthread_create (&tWorm_V01, NULL, Worm_V01, NULL);
		#endif
	}
	// Check for Worm_V02 infection:
	if (InfectionFlags[1] == 1)
	{
		cout << "Starting infection thread Worm_V02..." << endl;
		#ifdef WIN32
		tWorm_V02 = (HANDLE)_beginthread (Worm_V02, 0, NULL);
		#else
		pthread_create (&tWorm_V02, NULL, Worm_V02, NULL);
		#endif
	}

	char HostName[255];
	gethostname(HostName, 255);
	cout << "Hostname: " << HostName << endl;

	cout << "Starting Vulnerability Server 1.00..." << endl;
	cout << "Server Address: " << inet_ntoa(*(in_addr *)*gethostbyname (HostName)->h_addr_list) << ":" << SERVERPORT << endl;
	time_t rawtime;
	time ( &rawtime );
	cout << "Today is: " << asctime (localtime (&rawtime));

	// Create Vulnerability Thread.
	#ifdef WIN32
	tVulnerability = (HANDLE)_beginthread (Vulnerability, 0, NULL);
	WaitForSingleObject (tVulnerability, INFINITE);
	#else
	pthread_create (&tVulnerability, NULL, Vulnerability, NULL);
	pthread_join (tVulnerability, NULL);
	#endif
}

void SafeCall (int returnvalue, const char *FunctionName, int errorvalue)
{
	if (returnvalue == errorvalue)
	{
		cerr << "ERROR: " << FunctionName << endl;
		exit (-1);
	}
}

void SafeCallAssert (int returnvalue, const char *FunctionName, int expectedvalue)
{
	if (returnvalue != expectedvalue)
	{
		cerr << "ERROR: " << FunctionName << endl;
		exit (-1);
	}
}

char* RandomString (int Length, int CharOffset, int CharSpan)
{
	int size = rand()%Length+1;
	char *temp = new char[size];
	for (int z=0; z<size; z++)
		temp[z] = (char)(rand()%CharSpan+CharOffset);
	temp[size-1] = '\0';
	return temp;
}

char* RC4_Encrypt(unsigned char *keydata, char *plaintext, int Length)
{
	char *encrypted = new char[Length+1];
	RC4_KEY key;
	RC4_set_key(&key, strlen((const char*)keydata), keydata);

	// Encryption
	RC4(&key, Length, (const unsigned char*)plaintext, (unsigned char*)encrypted);
	encrypted[Length] = '\0';

	return encrypted;
}

// Compare two blocks of memory and returns true if they match else returns false.
bool memncmp (const char *block1, const char *block2, int size)
{
	for (int i=0; i<size; i++)
	{
		if (block1[i] != block2[i])
			return false;
	}
	return true;
}

void memncpy (char *dst, const char *src, int size)
{
	for (int i=0; i<size; i++)
		dst[i] = src[i];
}

// Threads.
THREAD_RETURN_TYPE Vulnerability (void *arg)
{
	while (true)
	{
		sin_size = sizeof (ClientAddress);
		SafeCall (NumOfBytesReceived = recvfrom (SocketFD, Buffer, MAXBUFFERSIZE-1, 0, (sockaddr *)&ClientAddress, &sin_size), "recvfrom()");
		Buffer[NumOfBytesReceived] = '\0';

		time_t rawtime;
		time ( &rawtime );
		cout << "=======================================================" << endl;
		cout << "Date/Time: " << asctime (localtime (&rawtime));
		cout << "Received : " << Buffer << endl;
		cout << "=======================================================" << endl;

		// Lock.
		#ifdef WIN32
		WaitForSingleObject (MutexLock, INFINITE);
		#else
		pthread_mutex_lock (&MutexLock);
		#endif
		
		// Check for Worm_V01 infection:
		if (VulnerabilityInstance.InfectionFlags[0] == 0 && strcmp(Buffer, WORM_V01_INFECTION) == 0)
		{
			cout << "###########################################" << endl;
			cout << "INFECTION: Server infected with Worm_V01..." << endl;
			cout << "###########################################" << endl;
			VulnerabilityInstance.InfectionFlags[0] = 1;
			#ifdef WIN32
			tWorm_V01 = (HANDLE)_beginthread (Worm_V01, 0, NULL);
			#else
			pthread_create (&tWorm_V01, NULL, Worm_V01, NULL);
			#endif
		}
		// Check for Worm_V02 infection:
		if (VulnerabilityInstance.InfectionFlags[1] == 0 && strstr(Buffer, WORM_V02_INFECTION) != NULL)
		{
			cout << "###########################################" << endl;
			cout << "INFECTION: Server infected with Worm_V02..." << endl;
			cout << "###########################################" << endl;
			VulnerabilityInstance.InfectionFlags[1] = 1;
			#ifdef WIN32
			tWorm_V02 = (HANDLE)_beginthread (Worm_V02, 0, NULL);
			#else
			pthread_create (&tWorm_V02, NULL, Worm_V02, NULL);
			#endif
			PeerIPList.push_back (inet_ntoa(ClientAddress.sin_addr));
		}

		// Unlock.
		#ifdef WIN32
		ReleaseMutex (MutexLock);
		#else
		pthread_mutex_unlock (&MutexLock);
		#endif
	}
	#ifndef WIN32
	return NULL;
	#endif
}

THREAD_RETURN_TYPE Worm_V01 (void *arg)
{
	// *********************************************** Network Related ************************************************
	#define W_V01_PORT						7011	// Worm_V01 Port.
	#define W_V01_SUBNET_ATTACK_INTERVAL	10		// Wait this much time before attacking another subnet.
	#define W_V01_IP_ATTACK_INTERVAL		1		// Wait this much time before attacking another IP.
	
	int W_V01_SocketFD;
	struct sockaddr_in W_V01_TheirAddress;
	struct sockaddr_in W_V01_Address;
	// ****************************************************************************************************************
	
	vector<string> SubnetList;
	stringstream AttackIPss;
	string AttackIP;

	fstream SubnetListIn("Worm_V01_Subnets.txt", std::ios::in);
	SubnetListIn.seekg(0, std::ios::end);
	int InFileSize = (int)SubnetListIn.tellg();
	if (!SubnetListIn || InFileSize < 0)
	{
		cerr << "ERROR: Opening file: Worm_V01_Subnets.txt" << endl;
		exit(-1);
	}
	SubnetListIn.seekg(std::ios::beg);

	string tempstring;
	while (!SubnetListIn.eof())
	{
		getline(SubnetListIn, tempstring, '\n');
		//if (SubnetListIn.eof())
			//break;
		cout << "Read: " << tempstring << endl;
		SubnetList.push_back(tempstring);
	}
	SubnetListIn.close();

	// Network Initialization.
	SafeCall(W_V01_SocketFD = socket(AF_INET, SOCK_DGRAM, 0), "socket()");
	W_V01_Address.sin_family = AF_INET;					// Socket family.
	W_V01_Address.sin_addr.s_addr = INADDR_ANY;			// Assigninig client IP.
	W_V01_Address.sin_port = htons(W_V01_PORT);			// W_V01_PORT.
	fill ((char*)&(W_V01_Address.sin_zero), (char*)&(W_V01_Address.sin_zero)+8, '\0');
	SafeCall(bind (W_V01_SocketFD, (sockaddr *)&W_V01_Address, sizeof (W_V01_Address)), "bind()");

	while (true)
	{
		// Attack all range of IPs in the subnet.
		for (int s=0; s < (int)SubnetList.size(); s++)
		{
			cout << "Worm_V01 Attacking subnet: " << SubnetList[s] << "0" << endl;
			for (int i=1; i<255; i++)
			{
				if (i%5 == 0)
				{
					#ifdef WIN32
					Sleep (W_V01_IP_ATTACK_INTERVAL*1000);
					#else
					sleep (W_V01_IP_ATTACK_INTERVAL);
					#endif
				}

				// Generate an IP from subnet list.
				AttackIPss.clear();
				AttackIPss << SubnetList[s] << i;
				AttackIPss >> AttackIP;
				cout << "Worm_V01 Attacking: " << AttackIP << endl;

				// Get an address/IP to attack.
				in_addr Their_addr;
				#ifdef WIN32
				unsigned long Their_addr_long = INADDR_NONE;
				Their_addr_long = inet_addr(AttackIP.c_str());
				if (Their_addr_long == INADDR_NONE || Their_addr_long == INADDR_ANY)		// Invalid address.
					continue;
				else
					Their_addr = *((in_addr *)&Their_addr_long);
				#else
				if (inet_aton(AttackIP.c_str(), &Their_addr) == 0)		// Invalid address.
					continue;
				#endif

				W_V01_TheirAddress.sin_family = AF_INET;						// Socket family.
				W_V01_TheirAddress.sin_addr = Their_addr;						// Their name/IP.
				W_V01_TheirAddress.sin_port = htons(SERVERPORT);				// Server Port.
				fill ((char*)&(W_V01_TheirAddress.sin_zero), (char*)&(W_V01_TheirAddress.sin_zero)+8, '\0');

				// Sending infectious payload.
				#ifdef WIN32
				WaitForSingleObject (MutexLock, INFINITE);
				#else
				pthread_mutex_lock (&MutexLock);
				#endif
				SafeCall(sendto(W_V01_SocketFD, WORM_V01_INFECTION, strlen(WORM_V01_INFECTION), 0, (sockaddr *)&W_V01_TheirAddress, sizeof(W_V01_TheirAddress)), "sendto()");
				#ifdef WIN32
				ReleaseMutex (MutexLock);
				#else
				pthread_mutex_unlock (&MutexLock);
				#endif
			}
			#ifdef WIN32
			Sleep (W_V01_IP_ATTACK_INTERVAL*1000);
			#else
			sleep (W_V01_IP_ATTACK_INTERVAL);
			#endif

			// Reset subnet list and start over.
			if (s == (int)SubnetList.size()-1)
				s = 0;
		}
	}
	#ifndef WIN32
	return NULL;
	#endif
}

// Worm_V02 related variables.
const char *W_V02_Keys[] = {"Worm_V02_18ef4fe50ead2d6", "Worm_V02_6f64793e0a3c2f6", "Worm_V02_a6bd7c3c866a4b6", "Worm_V02_0c4ad008a103c60", "Worm_V02_14356c0f858e130"};
const char *MagicKey = "04F2";

// *********************************************** Network Related ************************************************
#define W_V02_MAXBUFFERSIZE				512		// Maximum default buffersize.
#define W_V02_PORT						7012	// Worm_V01 Port.
#define W_V02_SUBNET_ATTACK_INTERVAL	10		// Wait this much time before attacking another subnet.
#define W_V02_IP_ATTACK_INTERVAL		1		// Wait this much time before attacking another IP.

int W_V02_SocketFD;
int W_V02_NumOfBytesReceived;
int W_V02_NumOfBytesSent;
char W_V02_Buffer[W_V02_MAXBUFFERSIZE];
struct sockaddr_in W_V02_TheirAddress;
struct sockaddr_in W_V02_Address;
struct sockaddr_in W_V02_PeerAddress;
// ****************************************************************************************************************

vector<string> SubnetList;
stringstream AttackIPss;
string AttackIP;

THREAD_RETURN_TYPE Worm_V02 (void *arg)
{
	fstream SubnetListIn("Worm_V02_Subnets.txt", std::ios::in);
	SubnetListIn.seekg(0, std::ios::end);
	int InFileSize = (int)SubnetListIn.tellg();
	if (!SubnetListIn || InFileSize < 0)
	{
		cerr << "ERROR: Opening file: Worm_V02_Subnets.txt" << endl;
		exit(-1);
	}
	SubnetListIn.seekg(std::ios::beg);

	string tempstring;
	while (!SubnetListIn.eof())
	{
		getline(SubnetListIn, tempstring, '\n');
		//if (SubnetListIn.eof())
			//break;
		cout << "Read: " << tempstring << endl;
		SubnetList.push_back(tempstring);
	}
	SubnetListIn.close();

	W_V02_Address.sin_family = AF_INET;					// Socket family.
	W_V02_Address.sin_addr.s_addr = INADDR_ANY;			// Assigninig client IP.
	W_V02_Address.sin_port = htons(W_V02_PORT);			// W_V01_PORT.
	fill ((char*)&(W_V02_Address.sin_zero), (char*)&(W_V02_Address.sin_zero)+8, '\0');

	// Network Initialization.
	SafeCall(W_V02_SocketFD = socket(AF_INET, SOCK_DGRAM, 0), "socket()");
	SafeCall(bind (W_V02_SocketFD, (sockaddr *)&W_V02_Address, sizeof (W_V02_Address)), "bind()");

	cout << "Starting Worm_V02_Receiver thread..." << endl;
	#ifdef WIN32
	tWorm_V02_Receiver = (HANDLE)_beginthread (Worm_V02_Receiver, 0, NULL);
	#else
	pthread_create (&tWorm_V02_Receiver, NULL, Worm_V02_Receiver, NULL);
	#endif

	srand((unsigned int)time(NULL));
	while (true)
	{
		// Attack all range of IPs in the subnet.
		for (int s=0; s < (int)SubnetList.size(); s++)
		{
			cout << "Worm_V02 Attacking subnet: " << SubnetList[s] << "0" << endl;
			for (int i=1; i<255; i++)
			{
				if (i%2 == rand()%3)
				{
					#ifdef WIN32
					Sleep (W_V02_IP_ATTACK_INTERVAL*1000);
					#else
					sleep (W_V02_IP_ATTACK_INTERVAL);
					#endif
				}

				unsigned int j = rand()%300+1;
				if (j<255)
				{
					// Generate an IP from subnet list.
					AttackIPss.clear();
					AttackIPss << SubnetList[s] << j;
					AttackIPss >> AttackIP;
					cout << "Worm_V02 Attacking: " << AttackIP << endl;

					// Get an address/IP to attack.
					in_addr Their_addr;
					#ifdef WIN32
					unsigned long Their_addr_long = INADDR_NONE;
					Their_addr_long = inet_addr(AttackIP.c_str());
					if (Their_addr_long == INADDR_NONE || Their_addr_long == INADDR_ANY)		// Invalid address.
						continue;
					else
						Their_addr = *((in_addr *)&Their_addr_long);
					#else
					if (inet_aton(AttackIP.c_str(), &Their_addr) == 0)		// Invalid address.
						continue;
					#endif

					W_V02_TheirAddress.sin_family = AF_INET;						// Socket family.
					W_V02_TheirAddress.sin_addr = Their_addr;						// Their name/IP.
					W_V02_TheirAddress.sin_port = htons(SERVERPORT);				// Server Port.
					fill ((char*)&(W_V02_TheirAddress.sin_zero), (char*)&(W_V02_TheirAddress.sin_zero)+8, '\0');

					// Sending infectious payload.
					string InfectiousPayload;
					char *temp = RandomString(15);
					InfectiousPayload = temp;
					delete []temp;
					InfectiousPayload += WORM_V02_INFECTION;
					temp = RandomString(30);
					InfectiousPayload += temp;
					delete []temp;

					#ifdef WIN32
					WaitForSingleObject (MutexLock, INFINITE);
					#else
					pthread_mutex_lock (&MutexLock);
					#endif
					SafeCall(sendto(W_V02_SocketFD, InfectiousPayload.c_str(), InfectiousPayload.size(), 0, (sockaddr *)&W_V02_TheirAddress, sizeof(W_V02_TheirAddress)), "sendto()");
					#ifdef WIN32
					ReleaseMutex (MutexLock);
					#else
					pthread_mutex_unlock (&MutexLock);
					#endif
				}
				else // Communicate with peers.
				{
					cout << "Worm_V02 Sending packets to peers." << endl;
					for (int k=0; k<(int)PeerIPList.size(); k++)
					{
						cout << "Worm_V02 Contacting Peer: " << PeerIPList[k] << endl;
						// Get an address/IP to attack.
						in_addr Their_addr;
						#ifdef WIN32
						unsigned long Their_addr_long = INADDR_NONE;
						Their_addr_long = inet_addr(PeerIPList[k].c_str());
						if (Their_addr_long == INADDR_NONE || Their_addr_long == INADDR_ANY)		// Invalid address.
							continue;
						else
							Their_addr = *((in_addr *)&Their_addr_long);
						#else
						if (inet_aton(AttackIP.c_str(), &Their_addr) == 0)		// Invalid address.
							continue;
						#endif

						W_V02_TheirAddress.sin_family = AF_INET;						// Socket family.
						W_V02_TheirAddress.sin_addr = Their_addr;						// Their name/IP.
						W_V02_TheirAddress.sin_port = htons(W_V02_PORT);				// Server Port.
						fill ((char*)&(W_V02_TheirAddress.sin_zero), (char*)&(W_V02_TheirAddress.sin_zero)+8, '\0');

						// TODO: Send encrypted message.
						string Message;
						Message = MagicKey;
						Message += WORM_V02_INFECTION;
						char *temp = RandomString(50);
						Message += temp;
						delete []temp;
						unsigned int RandomKey = rand()%5;
						char *EncryptedMessage = RC4_Encrypt((unsigned char *)W_V02_Keys[RandomKey], (char *)Message.c_str(), Message.size());

						#ifdef WIN32
						WaitForSingleObject (MutexLock, INFINITE);
						#else
						pthread_mutex_lock (&MutexLock);
						#endif
						SafeCall(sendto(W_V02_SocketFD, EncryptedMessage, Message.size(), 0, (sockaddr *)&W_V02_TheirAddress, sizeof(W_V02_TheirAddress)), "sendto()");
						#ifdef WIN32
						ReleaseMutex (MutexLock);
						#else
						pthread_mutex_unlock (&MutexLock);
						#endif

						delete []EncryptedMessage;
						cout << "Sent message: " << Message << " encrypted with key " << RandomKey << " to " << PeerIPList[k] << "." << endl;
					}
				}
			}
			#ifdef WIN32
			Sleep (W_V02_IP_ATTACK_INTERVAL*1000);
			#else
			sleep (W_V02_IP_ATTACK_INTERVAL);
			#endif

			// Reset subnet list and start over.
			if (s == (int)SubnetList.size()-1)
				s = 0;
		}
	}
	#ifndef WIN32
	return NULL;
	#endif
}

THREAD_RETURN_TYPE Worm_V02_Receiver (void *arg)
{
	#ifdef WIN32
	int W_02_sin_size;
	#else
	socklen_t W_02_sin_size;
	#endif
	while (true)
	{
		W_02_sin_size = sizeof (W_V02_PeerAddress);
		SafeCall (W_V02_NumOfBytesReceived = recvfrom (W_V02_SocketFD, W_V02_Buffer, W_V02_MAXBUFFERSIZE-1, 0, (sockaddr *)&W_V02_PeerAddress, &W_02_sin_size), "recvfrom()");
		W_V02_Buffer[W_V02_NumOfBytesReceived] = '\0';

		bool Verified = false;
		char *Decrypted;
		int i;
		for (i=0; i<5; i++)
		{
			Decrypted = RC4_Encrypt ((unsigned char *)W_V02_Keys[i], (char *)W_V02_Buffer, W_V02_NumOfBytesReceived);
			if (memncmp(Decrypted, MagicKey, 4) == true)
			{
				Verified = true;
				break;
			}
		}
		if (Verified == true)
			cout << "Message: " << Decrypted << " from " << inet_ntoa (W_V02_PeerAddress.sin_addr) << " decrypted with key " << i << endl;
		else
			cout << "Message couldn't be decrypted." << endl;

		// Add IP of sender if not already in the list.
		bool found = false;
		for (int j=0; j<(int)PeerIPList.size(); j++)
		{
			if (inet_ntoa(W_V02_PeerAddress.sin_addr) == PeerIPList[j])
			{
				found = true;
				break;
			}
		}
		if (found == false)
			PeerIPList.push_back(inet_ntoa(W_V02_PeerAddress.sin_addr));
	}
	#ifndef WIN32
	return NULL;
	#endif
}